"use strict";
var __assign =
  (this && this.__assign) ||
  function () {
    __assign =
      Object.assign ||
      function (t) {
        for (var s, i = 1, n = arguments.length; i < n; i++) {
          s = arguments[i];
          for (var p in s)
            if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
        }
        return t;
      };
    return __assign.apply(this, arguments);
  };
Object.defineProperty(exports, "__esModule", { value: true });
var opds_feed_parser_1 = require("opds-feed-parser");
var OpenSearchDescriptionParser_1 = require("./OpenSearchDescriptionParser");
var Cookie = require("js-cookie");
require("isomorphic-fetch");
const applocation_root = localStorage.getItem("MOBEBR_CONFIG_APPLICATION_ROOT");

/** Handles requests to OPDS servers. */
var DataFetcher = /** @class */ (function () {
  function DataFetcher(config) {
    if (config === void 0) {
      config = {};
    }
    this.proxyUrl = config.proxyUrl;
    this.adapter = config.adapter;
    this.authKey = "authCredentials";
  }
  DataFetcher.prototype.fetchOPDSData = function (url) {
    url = makeNewUrl(url);
    var _this = this;
    var parser = new opds_feed_parser_1.default();
    if (!this.adapter) {
      return Promise.reject({
        status: null,
        response: "No adapter has been configured in DataFetcher.",
        url: url,
      });
    }
    return new Promise(function (resolve, reject) {
      _this
        .fetch(url)
        .then(function (response) {
          response
            .text()
            .then(function (text) {
              if (_this.isErrorCode(response.status)) {
                reject({
                  status: response.status,
                  response: text,
                  url: url,
                  headers: response.headers,
                });
              }
              parser
                .parse(text)
                .then(function (parsedData) {
                  var _a;
                  resolve(
                    (_a = _this.adapter) === null || _a === void 0
                      ? void 0
                      : _a.call(_this, parsedData, url)
                  );
                })
                .catch(function (err) {
                  reject({
                    status: null,
                    response: "Failed to parse OPDS data",
                    url: url,
                  });
                });
            })
            .catch(function (error) {
              reject({
                status: response.status,
                response: error.message,
                url: url,
                headers: response.headers,
              });
            });
        })
        .catch(function (error) {
          return reject(error);
        });
    });
  };
  DataFetcher.prototype.fetchSearchDescriptionData = function (
    searchDescriptionUrl
  ) {
    searchDescriptionUrl = makeNewUrl(searchDescriptionUrl);
    var _this = this;
    var parser = new OpenSearchDescriptionParser_1.default();
    return new Promise(function (resolve, reject) {
      _this
        .fetch(searchDescriptionUrl)
        .then(function (response) {
          response.text().then(function (text) {
            if (_this.isErrorCode(response.status)) {
              reject({
                status: response.status,
                response: text,
                url: searchDescriptionUrl,
              });
            }
            parser
              .parse(text, searchDescriptionUrl)
              .then(function (openSearchDescription) {
                resolve(openSearchDescription);
              })
              .catch(function (err) {
                reject({
                  status: null,
                  response: "Failed to parse OPDS data",
                  url: searchDescriptionUrl,
                });
              });
          });
        })
        .catch(reject);
    });
  };
  DataFetcher.prototype.fetch = function (url, options) {
    url = makeNewUrl(url);
    if (options === void 0) {
      options = {};
    }
    options = Object.assign({ credentials: "same-origin" }, options);
    if (this.proxyUrl) {
      var formData = new window.FormData();
      formData.append("url", url);
      Object.assign(options, {
        method: "POST",
        body: formData,
      });
      url = this.proxyUrl;
    }
    options["headers"] = this.prepareAuthHeaders(options["headers"]);
    return fetch(url, options);
  };
  DataFetcher.prototype.setAuthCredentials = function (credentials) {
    if (credentials) {
      Cookie.set(this.authKey, JSON.stringify(credentials));
    }
  };
  DataFetcher.prototype.getAuthCredentials = function () {
    var credentials = Cookie.get(this.authKey);
    if (credentials) {
      return JSON.parse(credentials);
    }
  };
  DataFetcher.prototype.clearAuthCredentials = function () {
    Cookie.remove(this.authKey);
  };
  DataFetcher.prototype.prepareAuthHeaders = function (headers) {
    var _a;
    if (headers === void 0) {
      headers = {};
    }
    var credentials = this.getAuthCredentials();
    return __assign(
      {
        Authorization:
          (_a =
            credentials === null || credentials === void 0
              ? void 0
              : credentials.credentials) !== null && _a !== void 0
            ? _a
            : "",
        // server needs to know request came from JS in order to omit
        // 'Www-Authenticate: Basic' header, which triggers browser's
        // ugly basic auth popup
        "X-Requested-With": "XMLHttpRequest",
      },
      headers
    );
  };
  DataFetcher.prototype.isErrorCode = function (status) {
    return status < 200 || status >= 400;
  };
  return DataFetcher;
})();
exports.default = DataFetcher;

function makeNewUrl(url) {
  if (
    !url ||
    !applocation_root ||
    applocation_root == "" ||
    applocation_root == "/"
  )
    return url;
  if (url.indexOf(applocation_root) != -1) return url;
  if (url.indexOf("http") != -1) {
    let urlList = url.split("/");
    urlList.splice(3, 0, applocation_root.replace(/(^\/*)/g, ""));
    url = urlList.join("/");
    return url;
  } else {
    return applocation_root + url;
  }
}
